package main

import (
	"context"
	"flag"
	"fmt"
	"github.com/gin-gonic/gin"
	"log"
	"monitor"
	"net/http"
	_ "net/http/pprof"
	"os"
	"os/signal"
	"runtime"
	"strconv"
	"syscall"
	"time"
)

var (
	PORT       = flag.Uint("PORT", 3001, "")
	PPROF_PORT = flag.Uint("PPROF_PORT", 6666, "")
)

func init() {
	flag.Parse()
	log.SetPrefix("[INFO ] ")
	log.SetFlags(log.Ldate | log.Lmicroseconds)

	if "development" == os.Getenv("EMAIL_MODE") {
		log.SetFlags(log.Ldate | log.Lmicroseconds | log.Lshortfile)
	}

	_numCPU := runtime.NumCPU()
	if "" != os.Getenv("EMAIL_NUMCPU") {
		_numCPU, _ = strconv.Atoi(os.Getenv("EMAIL_NUMCPU"))
	}
	runtime.GOMAXPROCS(_numCPU)

	monitor.Init()
}

func pprof() {
	go func() {
		log.Println(http.ListenAndServe(fmt.Sprintf(":%d", *PPROF_PORT), nil))
	}()
}

func main() {
	if "production" != os.Getenv("EMAIL_MODE") {
		pprof()
	}

	log.Println("Hello, EMail!")

	log.Println("server port:", *PORT)

	// time.Sleep(time.Duration(3) * time.Second)

	_r := gin.Default()

	//  跨域
	if _acao := os.Getenv("EMAIL_ACAO"); "" != _acao {
		_r.Use(cors(_acao))
	}

	{
		_r.GET("actuator/health", api_health)
		_r.GET("api/time/get", api_user_login)
		// _r.GET("api/email/send", api_email_send)
		_r.GET("api/email/sendByTLS", api_email_sendByTLS)
	}

	_serv := &http.Server{
		Addr:           fmt.Sprintf(":%d", *PORT),
		Handler:        _r,
		ReadTimeout:    5 * time.Second,
		WriteTimeout:   5 * time.Second,
		MaxHeaderBytes: 1 << 20,
	}

	go func() {
		if _err := _serv.ListenAndServe(); nil != _err && _err != http.ErrServerClosed {
			log.Fatal(_err)
		}
	}()

	// Wait for interrupt signal to gracefully shutdown the server with
	// a timeout of 5 seconds.
	_quit := make(chan os.Signal)
	// kill (no param) default send syscall.SIGTERM
	// kill -2 is syscall.SIGINT
	// kill -9 is syscall.SIGKILL but can't be catch, so don't need add it
	signal.Notify(_quit, syscall.SIGINT, syscall.SIGTERM)
	<-_quit
	log.Println("shutdown")

	_ctx, _cancel := context.WithTimeout(context.Background(), 1*time.Second)
	defer _cancel()
	if _err := _serv.Shutdown(_ctx); nil != _err {
		log.Fatal(_err)
	}

	// catching _ctx.Done(). timeout of 1 seconds.
	select {
	case <-_ctx.Done():
		log.Println("timeout of 1 seconds")
	}
	log.Println("exit")
}

func cors(acao string) gin.HandlerFunc {
	return func(c *gin.Context) {
		c.Header("Access-Control-Allow-Origin", acao)
		c.Next()
	}
}
